#ifndef ICODEEDITOR_H
#define ICODEEDITOR_H

#include "IEditor.h"

#include <QtCore/QObject>
#include <QtCore/QList>

QT_BEGIN_NAMESPACE
class QMenu;
class QTextBlock;
class QIcon;
class QRect;
class QPoint;
QT_END_NAMESPACE

namespace CodeEdit {

class ITextMark : public QObject
{
    Q_OBJECT

public:
    ITextMark(QObject *parent = 0) : QObject(parent) { }
    virtual ~ITextMark() { }

    virtual QIcon icon() const = 0;

    virtual void updateLineNumber(int lineNumber) = 0;
    virtual void updateBlock(const QTextBlock &block) = 0;
    virtual void removeFromEditor() = 0;
    virtual void documentClosing() = 0;
};

typedef QList<ITextMark*> TextMarks;

class ITextMarkable : public QObject
{
    Q_OBJECT

public:
    ITextMarkable(QObject *parent = 0) : QObject(parent) { }
    virtual ~ITextMarkable() { }

    virtual bool addMark(ITextMark *mark, int line) = 0;
    virtual TextMarks marksAt(int line) const = 0;
    virtual void removeMark(ITextMark *mark) = 0;
    virtual bool hasMark(ITextMark *mark) const = 0;
    virtual void updateMark(ITextMark *mark) = 0;
};

class ICodeEditor : public IEditor
{
    Q_OBJECT

public:
    enum PositionOperation {
        Current = 1,
        EndOfLine = 2,
        StartOfLine = 3,
        Anchor = 4,
        EndOfDoc = 5
    };

    ICodeEditor() { }
    virtual ~ICodeEditor() { }

    virtual int find(const QString &string) const = 0;

    virtual void gotoLine(int line, int column = 0) = 0;

    virtual int position(PositionOperation posOp = Current, int at = -1) const = 0;
    virtual void convertPosition(int pos, int *line, int *column) const = 0;
    virtual QRect cursorRect(int pos = -1) const = 0;

    virtual QString contents() const = 0;
    virtual QString selectedText() const = 0;
    virtual QString textAt(int pos, int length) const = 0;
    virtual QChar characterAt(int pos) const = 0;

    virtual void triggerCompletions() = 0;
    virtual void triggerQuickFix() = 0;

    virtual ITextMarkable *markableInterface() = 0;

    virtual void setContextHelpId(const QString&) = 0;

    virtual void setTextCodec(QTextCodec*) = 0;
    virtual QTextCodec *textCodec() const = 0;

signals:
    void contentsChanged();
    void contentsChangedBecauseOfUndo();
    void markRequested(CodeEdit::ICodeEditor *editor, int line);
    void markContextMenuRequested(CodeEdit::ICodeEditor *editor, int line, QMenu *menu);
    void tooltipRequested(CodeEdit::ICodeEditor *editor, const QPoint &globalPos, int position);
    void contextHelpIdRequested(CodeEdit::ICodeEditor *editor, int position);
};

} // namespace CodeEdit

#endif // ICODEEDITOR_H
